package videoCapture;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import javax.imageio.ImageIO;

import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber.Exception;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class VideoP2P1 implements Runnable {
	public static final int PORT = 5001;
	public static final int ServerPORT = 4000;
	private DatagramSocket dataSocket;
	private DatagramPacket dataPacket;
	private byte sendByte[];
	private static int BUFSIZE = 1024;
	private byte[] IP = { (byte) 127, (byte) 0, (byte) 0, (byte) 1 };
	private byte[] ServerIP = { (byte) 125, (byte) 221, (byte) 225, (byte) 128 };
	private String title = "chat1";
	ByteArrayOutputStream out;
	BufferedImage bimg;
	
	
	private int ColorLimit = 1 * 25; // 向服务器发送数据的间距
	private int ColorConter = 0; // 计数器

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public byte[] getIP() {
		return IP;
	}

	public void setIP(byte[] iP) {
		IP = iP;
	}

	public VideoP2P1() throws SocketException {
		dataSocket = new DatagramSocket(PORT);
		sendByte = new byte[BUFSIZE];
		dataPacket = new DatagramPacket(sendByte, BUFSIZE);
		out = new ByteArrayOutputStream();
	}

	public void start() throws Exception, java.lang.Exception {

		final CanvasFrame canvas = new CanvasFrame(title);
		final OpenCVFrameGrabber grabber = OpenCVFrameGrabber.createDefault(0);
		IplImage image = null;

		// canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		canvas.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				canvas.dispose();
				try {
					grabber.stop();
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				System.exit(0);
			}
		});
		grabber.start();
		image = grabber.grab();
		canvas.setCanvasSize(image.width(), image.height());
		canvas.setVisible(true);

		while (canvas.isVisible()) {
			try {
				image = grabber.grab();
			} catch (Exception e) {
				e.printStackTrace();
			}
			canvas.showImage(image);
			// System.out.println(image.imageSize());

			SendImg(image);
			Thread.sleep(40);
		}

	}

	// 此方法导致运行效率极差，需要重点优化
	public void SendImg(IplImage image) throws IOException {
		// ImageIO.setUseCache(false);
		bimg = image.getBufferedImage();

		// WritableRaster raster = bimg .getRaster();
		// SampleModel s = raster.getSampleModel();
		// System.out.println(s.getDataType() + " " + s.getHeight() + " " +
		// s.getWidth() + " " + s.getNumBands() );
		// DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
		ImageIO.write(bimg, "jpg", out);
		byte[] imgBuf = out.toByteArray();
		// byte[] imgBuf = ((DataBufferByte)
		// bimg.getData().getDataBuffer()).getData();
		int index = 0;
		int dataSize = 0;
		boolean flag =false;	//为true则向服务器发送一份数据
		// 每过一段时间向指定的服务器发送一份数据
		if (ColorConter++ >= ColorLimit) {
			ColorConter = 0;
			flag = true;
		//	System.out.println("mark");
		}
		while (index < imgBuf.length) {
			int i;
			for (i = 0; i < BUFSIZE && (index + i) < imgBuf.length; i++) {

				sendByte[i] = imgBuf[index + i];
			}
			index += i;
			dataSize += i;
			dataPacket = new DatagramPacket(sendByte, i,
					InetAddress.getByAddress(IP), VideoP2P2.PORT);
			dataSocket.send(dataPacket);
			if(flag){
				
				dataPacket = new DatagramPacket(sendByte, i,
						InetAddress.getByAddress(ServerIP), ServerPORT);
				dataSocket.send(dataPacket);
			}
		}

		dataPacket = new DatagramPacket(new byte[0], 0,
				InetAddress.getByAddress(IP), VideoP2P2.PORT);
		dataSocket.send(dataPacket);
		if(flag){
			
			dataPacket = new DatagramPacket(new byte[0], 0,
					InetAddress.getByAddress(ServerIP), ServerPORT);
			dataSocket.send(dataPacket);
		}

		// out.close();
		out.reset();
	}

	public void SendToServer() {

	}

	public void SendImg2(IplImage image) throws IOException {
		// ImageIO.setUseCache(false);
		BufferedImage bimg = image.getBufferedImage();
		// ByteArrayOutputStream out = new ByteArrayOutputStream();

		// WritableRaster raster = bimg .getRaster();
		// SampleModel s = raster.getSampleModel();
		// System.out.println(s.getDataType() + " " + s.getHeight() + " " +
		// s.getWidth() + " " + s.getNumBands() );
		// DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
		// ImageIO.write(bimg, "jpg", out);
		// byte[] imgBuf = out.toByteArray();
		byte[] imgBuf = ((DataBufferByte) bimg.getData().getDataBuffer())
				.getData();
		int index = 0;
		int dataSize = 0;
		while (index < imgBuf.length) {
			int i;
			for (i = 0; i < BUFSIZE && (index + i) < imgBuf.length; i++) {
				// System.out.println("client "+i);
				sendByte[i] = imgBuf[index + i];
			}
			index += i;
			dataSize += i;
			dataPacket = new DatagramPacket(sendByte, i,
					InetAddress.getByAddress(IP), VideoP2P2.PORT);
			dataSocket.send(dataPacket);
		}
		// System.out.println("Video dataSize " + dataSize);
		dataSocket.send(new DatagramPacket(new byte[0], 0, InetAddress
				.getByAddress(IP), VideoP2P2.PORT));
		// out.close();
	}

	// public void SendImg3(IplImage image) throws IOException {
	// int index = 0;
	// int dataSize = 0;
	// while (index < imgBuf.length) {
	// int i;
	// for (i = 0; i < BUFSIZE && (index + i) < imgBuf.length; i++) {
	// // System.out.println("client "+i);
	// sendByte[i] = imgBuf[index + i];
	// }
	// index += i;
	// dataSize += i;
	// dataPacket = new DatagramPacket(sendByte, i,
	// InetAddress.getByAddress(IP), VideoP2P2.PORT);
	// dataSocket.send(dataPacket);
	// }
	// }

	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			this.start();
		} catch (java.lang.Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static void main(String[] args) throws java.lang.Exception {

		VideoP2P1 p1 = new VideoP2P1();
		// System.out.println(args.length);
		if (args.length != 0) {
			String[] st = args[0].split("\\.");
			byte[] tb = { (byte) Integer.parseInt(st[0]),
					(byte) Integer.parseInt(st[1]),
					(byte) Integer.parseInt(st[2]),
					(byte) Integer.parseInt(st[3]) };
			p1.setIP(tb);
		}
		// p1.start();
		Thread thread = new Thread(p1);
		thread.start();
	}

}
